package com.sophia.common.xmlbean.util;


import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sophia.pojo.AbstractModelObject;
/**
 * 
 * <p>Title:Health</p>
 * <p>BaseXMLPojo</p>
 * 
 * Alex Apr 12, 2011 3:33:19 PM create
 * @author <a href='wanghao924@126.com'>Alex</a>
 * QQ: 873987060;
 * @version 1.0
 */
public class BaseXMLPojo extends AbstractModelObject implements Serializable{

	private static final long serialVersionUID = 1L;

	// 节点名
	protected String nodeName = "";

	// 该节点的子节点list
	protected List nodeList = new ArrayList();

	// 该节点的属性map
	protected Map atttrMap = new HashMap();

	// 构造方法(根据实际情况重写)
	public BaseXMLPojo() {
		// 赋值节点名
		nodeName = "";

		// 赋值节点属性map

		// 赋值子节点list
	}

	public Map getAtttrMap() {
		return atttrMap;
	}

	public void setAtttrMap(Map atttrMap) {
		this.atttrMap = atttrMap;
	}

	public String getNodeName() {
		return nodeName;
	}

	/**
	 * 
	 * Des:增加或修改属性map中某个key所对应的value值<br>
	 * Logic:<br>
	 * Alex crated the method at 2011-3-14
	 */
	public void updateAtttrMapValue(String key,String value){
		atttrMap.put(key,value);
	}
	
	/**
	 * 
	 * Des:获取属性map中某个key所对应的value值<br>
	 * Logic:<br>
	 * Alex crated the method at 2011-3-14
	 */
	public String getAtttrMapValue(String key){
		return (String)atttrMap.get(key);
	}
	
	/**
	 * 
	 * Des:通过XML内容为该对象赋值<br>
	 * Logic:<br>
	 * Alex crated the method at 2011-3-9
	 */
	public Long toObject(String xmlContent) throws Exception {
		// 将XML字符串转换成DOC对象
		Document doc = PojoXMLUtil.getDocumentByData(xmlContent);

		// 获取对应该对象的指定节点
		NodeList ndl = doc.getElementsByTagName(nodeName);
		if (ndl.getLength() > 0) {
			Node nd = ndl.item(0);
			// 赋值属性map
			NamedNodeMap nnm = nd.getAttributes();
			if (nnm.getLength() > 0) {
				for (int i = 0; i < nnm.getLength(); i++) {
					Node n = nnm.item(i);
					atttrMap.put(n.getNodeName(), n.getNodeValue());
				}
			}
			
			//返回该节点所处的DOM对象
			Document ndoc = PojoXMLUtil.getDocumentByData(PojoXMLUtil.getDomXml(nd)) ;

			// 赋值子节点list
			for (Iterator i = nodeList.iterator(); i.hasNext();) {
				String fieldName = (String) i.next();
				Class[] fieldClass = new Class[1];

				Field field = getClass().getDeclaredField(fieldName);
				if (field != null) {
					fieldClass[0] = field.getType();

					if (List.class.equals(fieldClass[0])) {
						// 如果子节点是List<T>类型
						Type listType = field.getGenericType(); 
						ParameterizedType pt = (ParameterizedType) listType;
						//得到泛型里的class类型对象。
		                Class genericClazz = (Class)pt.getActualTypeArguments()[0]; 
		                
		                List list = new ArrayList();
		                
		                NodeList sndl= ndoc.getElementsByTagName(fieldName);
		                for(int j=0;j<sndl.getLength();j++){
		                	BaseXMLPojo obj = (BaseXMLPojo)genericClazz.newInstance();
		                	obj.toObject(PojoXMLUtil.getDomXml(sndl.item(j)));
		                	list.add(obj);
		                }
		                   
						Method method = getClass().getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1),fieldClass);
						method.invoke(this,list);


					} else {
						// 如果子节点是其他类型
						NodeList sndl= ndoc.getElementsByTagName(fieldName);
						if(sndl.getLength()>0){
							BaseXMLPojo obj = (BaseXMLPojo) fieldClass[0].newInstance();
							obj.toObject(PojoXMLUtil.getDomXml(sndl.item(0)));
							
							Method method = getClass().getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1),fieldClass);
							method.invoke(this,obj);
						}
					}
				}
			}
			
			return 1L;
		}
		
		return 0L;
			
	}

	/**
	 * 
	 * Des:将对象转化成Node对象<br>
	 * Logic:<br>
	 * Alex crated the method at 2011-3-10
	 */
	public Node toNode() throws Exception{
		if (!"".equals(nodeName)){
			
			Document doc = PojoXMLUtil.createDocument();   
            // 文档对象创建一个根元素  
            Element root = doc.createElement(nodeName);   
            doc.appendChild(root);   
            
            //添加属性
            if(atttrMap.size()>0){
            	Set set = atttrMap.entrySet();
            	for(Iterator i = set.iterator();i.hasNext();){
            		Map.Entry mapEntry = (Map.Entry)i.next();
            		root.setAttribute((String)mapEntry.getKey(),(String)mapEntry.getValue());
            	}
            }
            
            
            //添加子节点
            if(nodeList.size()>0){
            	for(Iterator i = nodeList.iterator();i.hasNext();){
            		String fieldName = (String) i.next();
					Class[] fieldClass = new Class[1];

					Field field = getClass().getDeclaredField(fieldName);
					if (field != null) {
						fieldClass[0] = field.getType();

						if (List.class.equals(fieldClass[0])) {
							// 如果是List类型
							Method method = getClass().getMethod("get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));

							List list = (List) method.invoke(this);
							if (list!=null && list.size()>0){
								for (Iterator j = list.iterator(); j.hasNext();) {
									BaseXMLPojo bxmlp = (BaseXMLPojo) j.next();
									if(bxmlp!=null){
										Node node = bxmlp.toNode();
										Node tmpNode = doc.importNode(node,true);
										root.appendChild(tmpNode);
									}
								}
							}

						} else {
							// 如果是其他类型
							Method method = getClass().getMethod("get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
							BaseXMLPojo obj = (BaseXMLPojo) method.invoke(this);
							if(obj!=null){
								Node node = obj.toNode();
								Node tmpNode = doc.importNode(node,true);
								root.appendChild(tmpNode);
							}
						}
					}
            	}
            }
       
			return doc.getDocumentElement();
		}
		return null;
	}
	
	//********************getter、setter**************************************
	public String getCode(){
		Object o = atttrMap.get("code");
		String r = "";
		if(o!=null)r=(String)o;
		return r;
	}
	@SuppressWarnings("unchecked")
	public void setCode(String code){
		if(code == null)
			atttrMap.put("code", "");
		else
			atttrMap.put("code", code);
	}
	public String getValue(){
		Object o = atttrMap.get("value");
		String r = "";
		if(o!=null)r=(String)o;
		return r;
	}
	@SuppressWarnings("unchecked")
	public void setValue(String value){
		if(value == null)
			atttrMap.put("value", "");
		else
			atttrMap.put("value", value);
	}
	public String getCodeSystem(){
		Object o = atttrMap.get("codeSystem");
		String r = "";
		if(o!=null)r=(String)o;
		return r;
	}
	@SuppressWarnings("unchecked")
	public void setCodeSystem(String codeSystem){
		if(codeSystem == null)
			atttrMap.put("codeSystem", "");
		else
			atttrMap.put("codeSystem", codeSystem);
	}
	public String getAdditionDescription(){
		Object o = atttrMap.get("additionDescription");
		String r = "";
		if(o!=null)r=(String)o;
		return r;
	}
	@SuppressWarnings("unchecked")
	public void setAdditionDescription(String additionDescription){
		if(additionDescription == null)
			atttrMap.put("additionDescription", "");
		else
			atttrMap.put("additionDescription", additionDescription);
	}
}

